package com.tianhua.amis4j.service.parser;

import com.coderman.model.meta.bean.back.*;
import com.coderman.model.meta.bean.dsl.CodeFactoryService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tianhua.amis4j.service.admin.WebCodeTemplateConfigService;
import com.tianhua.amis4j.service.engine.CodeFactoryRoute;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Description:
 * date: 2022/5/10
 *
 * @author fanchunshuai
 * @version 1.0.0
 * @since JDK 1.8
 */
@Component(value = "abstractTemplateParse")
@Slf4j
public class AbstractTemplateParse {
    @Autowired
    private WebCodeTemplateConfigService webArchTemplateConfigService;

    @Autowired
    private CodeFactoryRoute codeFactoryRoute;

    /**
     * 根据模版名称从db中获取模版配置内容
     *
     * @param archTemplateConfigMap
     */
    public void rebuildArchTemplateConfigMap(String archName, Map<String, List<WebCodeTemplateBean>> archTemplateConfigMap) {
        Map<String, List<WebCodeTemplateBean>> tempMap = archTemplateConfigMap;
        tempMap.forEach((k, v) -> {
            List<WebCodeTemplateBean> webArchTemplateBeanList = new ArrayList<>();
            v.stream().forEach(webArchTemplateBean -> {
                WebCodeTemplateBean newBean = webArchTemplateConfigService.getByTemplateNameAndArchName(archName, webArchTemplateBean.getTemplateName());
                if (newBean != null) {
                    newBean.setModuleCode(k);
                    webArchTemplateBeanList.add(newBean);
                } else {
                    log.error("找不到对应的框架应用模版.....");
                }
            });
            archTemplateConfigMap.put(k, webArchTemplateBeanList);
        });
    }

    /**
     * 获取模块描述或者模块名称或者模块标题
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getModuleCode(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        return moduleCode;
    }



    /**
     * 获取模块描述或者模块名称或者模块标题
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getModuleTitle(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        ModuleBean moduleBean = projectSnapShotBean.getModuleBeanMap().get(moduleCode);
        if (moduleBean == null) {
            return "null";
        }
        return moduleBean.getModuleDesc();
    }
    /**
     * 获取模块描述或者模块名称或者模块标题
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getModuleRouteUrl(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        ModuleBean moduleBean = projectSnapShotBean.getModuleBeanMap().get(moduleCode);
        if (moduleBean == null) {
            return "null";
        }
        return moduleBean.getRouteUrl();
    }



    /**
     * 获取模块描述或者模块名称或者模块标题
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getModuleContext(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        ModuleBean moduleBean = projectSnapShotBean.getModuleBeanMap().get(moduleCode);
        if (moduleBean == null) {
            return "null";
        }
        return moduleBean.getContextName();
    }
    /**
     * 获取保存api
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getInsertApi(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            return "/" + moduleCode + "/save";
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("save") || apiBean.getApiUrl().contains("insert") || apiBean.getApiUrl().contains("submit")) {
                return apiBean.getApiUrl();
            }
        }
        return "/" + moduleCode + "/save";
    }

    public String getProjectDevUrl(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        return projectSnapShotBean.getProjectBean().getDevUrl();
    }


    public String getProjectTestUrl(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        return projectSnapShotBean.getProjectBean().getTestUrl();
    }

    public String getProjectPreUrl(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        return projectSnapShotBean.getProjectBean().getPreUrl();
    }

    public String getProjectProUrl(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        return projectSnapShotBean.getProjectBean().getProUrl();
    }


    /**
     * 获取修改api
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getUpdateApi(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);
        if (CollectionUtils.isEmpty(apiBeanList)) {
            return "/" + moduleCode + "/update";
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.isPost() && apiBean.getApiUrl().toLowerCase().contains("update")) {
                return apiBean.getApiUrl();
            }
        }
        return "/" + moduleCode + "/update";
    }
    /**
     * 获取修改api
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getDetailApi(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);
        if (CollectionUtils.isEmpty(apiBeanList)) {
            return "/" + moduleCode + "/getById";
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.isGet() && apiBean.getApiUrl().toLowerCase().contains("getby")) {
                return apiBean.getApiUrl();
            }
        }
        return "/" + moduleCode + "/getById";
    }

    /**
     * 获取分页列表api
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getPageApi(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);
        if (CollectionUtils.isEmpty(apiBeanList)) {
            return "/" + moduleCode + "/pagelist";
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("page")) {
                return apiBean.getApiUrl();
            }
        }
        return "/" + moduleCode + "/pagelist";
    }

    /**
     * 获取删除api
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getDeleteApi(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);
        if (CollectionUtils.isEmpty(apiBeanList)) {
            return "/" + moduleCode + "/delete";
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("delete")) {
                return apiBean.getApiUrl();
            }
        }
        return "/" + moduleCode + "/delete";
    }



    /**
     * 从web-dsl中获取已经渲染好的模版代码
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getInsertForm(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<WebCodeBean> webDslConfigBeanList = projectSnapShotBean.getWebDslConfigBeanList();
        if (CollectionUtils.isEmpty(webDslConfigBeanList)) {
            return "{}";
        }
        for (WebCodeBean webDslConfigBean : webDslConfigBeanList) {
            if (webDslConfigBean.getProjectCode().equals(projectSnapShotBean.getProjectCode())
                    && webDslConfigBean.getModuleCode().equals(moduleCode) && (webDslConfigBean.getApiUrl().contains("save") || webDslConfigBean.getApiUrl().contains("insert"))) {
                return webDslConfigBean.getWebDslJson();
            }
        }
        return "{}";
    }

    /**
     * 从web-dsl中获取已经渲染好的模版代码
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getDetailForm(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<WebCodeBean> webDslConfigBeanList = projectSnapShotBean.getWebDslConfigBeanList();
        if (CollectionUtils.isEmpty(webDslConfigBeanList)) {
            return "{}";
        }
        for (WebCodeBean webDslConfigBean : webDslConfigBeanList) {
            if (webDslConfigBean.getProjectCode().equals(projectSnapShotBean.getProjectCode())
                    && webDslConfigBean.getModuleCode().equals(moduleCode) && (webDslConfigBean.getApiUrl().contains("get") || webDslConfigBean.getApiUrl().contains("detail"))) {
                return webDslConfigBean.getWebDslJson();
            }
        }
        return "{}";
    }


    /**
     * 从web-dsl中获取已经渲染好的模版代码
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getPageForm(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<WebCodeBean> webDslConfigBeanList = projectSnapShotBean.getWebDslConfigBeanList();
        if (CollectionUtils.isEmpty(webDslConfigBeanList)) {
            return "{}";
        }
        for (WebCodeBean webDslConfigBean : webDslConfigBeanList) {
            if (webDslConfigBean.getProjectCode().equals(projectSnapShotBean.getProjectCode())
                    && webDslConfigBean.getModuleCode().equals(moduleCode) && (webDslConfigBean.getApiUrl().contains("page"))) {
                return webDslConfigBean.getWebDslJson();
            }
        }
        return "{}";
    }



    /**
     * 从web-dsl中获取已经渲染好的模版代码
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getUpdateForm(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        List<WebCodeBean> webDslConfigBeanList = projectSnapShotBean.getWebDslConfigBeanList();
        if (CollectionUtils.isEmpty(webDslConfigBeanList)) {
            return "{}";
        }
        for (WebCodeBean webDslConfigBean : webDslConfigBeanList) {
            if (webDslConfigBean.getProjectCode().equals(projectSnapShotBean.getProjectCode())
                    && webDslConfigBean.getModuleCode().equals(moduleCode) && (webDslConfigBean.getApiUrl().contains("update"))) {
                return webDslConfigBean.getWebDslJson();
            }
        }
        return "{}";
    }

    /**
     * 获取插入标题
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    private String getInsertApiTitle(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        String moduleName = getModuleTitle(moduleCode, projectSnapShotBean);

        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            if(!moduleName.equals("null")){
                return "新增"+moduleName.replace("管理","");
            }else {
                return "新增";
            }
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("save") || apiBean.getApiUrl().contains("insert") || apiBean.getApiUrl().contains("submit")) {
                return apiBean.getApiDoc();
            }
        }
        return "新增";
    }

    /**
     * 获取修改标题
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getUpdateApiTitle(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        String moduleName = getModuleTitle(moduleCode, projectSnapShotBean);

        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            if(!moduleName.equals("null")){
                return "修改"+moduleName.replace("管理","");
            }else {
                return "修改";
            }
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("update") || apiBean.getApiUrl().contains("edit")) {
                return apiBean.getApiDoc();
            }
        }
        return "修改";
    }

    /**
     * 获取详情标题
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public String getDetailApiTitle(String moduleCode, ProjectSnapShotBean projectSnapShotBean) {
        String moduleName = getModuleTitle(moduleCode, projectSnapShotBean);

        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            if(!moduleName.equals("null")){
                return "查看"+moduleName.replace("管理","");
            }else {
                return "查看";
            }
        }
        for (ApiBean apiBean : apiBeanList) {
            if (apiBean.getApiUrl().contains("detail") || apiBean.getApiUrl().contains("get")) {
                return apiBean.getApiDoc();
            }
        }
        return "查看";
    }



    /**
     * 获取表单输入属性参数
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public List<Map<String,Object>> getInsertApiParam(String moduleCode, ProjectSnapShotBean projectSnapShotBean, String webAppName) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            return Lists.newArrayList();
        }
        ApiBean apiBean = null;
        for (ApiBean api : apiBeanList) {
            if (api.getApiUrl().contains("save") || api.getApiUrl().contains("insert") || api.getApiUrl().contains("submit")) {
                apiBean = api;
            }
        }

        if(apiBean != null && CollectionUtils.isNotEmpty(apiBean.getParamBeanList())){
            Optional<ParamBean> paramBeanOptional = apiBean.getParamBeanList().stream().filter(paramBean -> paramBean.isModelParam()).findFirst();
            if(paramBeanOptional.isPresent()){

                ParamBean paramBean = paramBeanOptional.get();
                List<FieldBean> fieldBeanList = paramBean.getFieldBeanList();
                List<Map<String,Object>> fieldMetaList = new ArrayList<>();
                for (FieldBean fieldBean : fieldBeanList){
                    Map<String,Object> fieldAttrMap = new HashMap<>();

                    FieldExtendBean fieldExtendBean = fieldBean.getFieldExtendBean();

                    fieldAttrMap.put("fieldName",fieldBean.getFieldName());
                    fieldAttrMap.put("fieldDesc",fieldBean.getFieldDesc());
                    fieldAttrMap.put("required",fieldExtendBean.isRequired());

                    String inputType = getFieldInputType(fieldBean,webAppName);

                    fieldAttrMap.put("inputType",inputType);
                    fieldAttrMap.put("maxLength",fieldExtendBean.getMaxLength());
                    fieldAttrMap.put("minLength",fieldExtendBean.getMinLength());
                    fieldAttrMap.put("searchInPage",fieldExtendBean.isSearchInPage());
                    //如果不为空或者在插入表单中存在则进行渲染
                    if (fieldExtendBean.isRequired() || fieldExtendBean.isInInsertForm()){
                        fieldMetaList.add(fieldAttrMap);
                    }
                }

                return fieldMetaList;
            }
        }


        return Lists.newArrayList();
    }

    /**
     * 获取表单详情属性参数
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public List<Map<String,Object>> getDetailApiParam(String moduleCode, ProjectSnapShotBean projectSnapShotBean, String webAppName) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            return Lists.newArrayList();
        }
        ApiBean apiBean = null;
        for (ApiBean api : apiBeanList) {
            if (api.getApiUrl().toLowerCase().contains("getyby") || api.getApiUrl().toLowerCase().contains("detail")) {
                apiBean = api;
            }
        }

        if(apiBean != null && CollectionUtils.isNotEmpty(apiBean.getParamBeanList())){
            Optional<ParamBean> paramBeanOptional = apiBean.getParamBeanList().stream().filter(paramBean -> paramBean.isModelParam()).findFirst();
            if(paramBeanOptional.isPresent()){

                ParamBean paramBean = paramBeanOptional.get();
                List<FieldBean> fieldBeanList = paramBean.getFieldBeanList();
                List<Map<String,Object>> fieldMetaList = new ArrayList<>();
                for (FieldBean fieldBean : fieldBeanList){
                    Map<String,Object> fieldAttrMap = new HashMap<>();

                    FieldExtendBean fieldExtendBean = fieldBean.getFieldExtendBean();

                    fieldAttrMap.put("fieldName",fieldBean.getFieldName());
                    fieldAttrMap.put("fieldDesc",fieldBean.getFieldDesc());
                    fieldAttrMap.put("required",fieldExtendBean.isRequired());

                    String inputType = getFieldInputType(fieldBean,webAppName);

                    fieldAttrMap.put("inputType",inputType);
                    fieldAttrMap.put("maxLength",fieldExtendBean.getMaxLength());
                    fieldAttrMap.put("minLength",fieldExtendBean.getMinLength());
                    fieldAttrMap.put("searchInPage",fieldExtendBean.isSearchInPage());
                    //如果不为空或者在插入表单中存在则进行渲染
                    if (fieldExtendBean.isRequired() || fieldExtendBean.isInDetailForm()){
                        fieldMetaList.add(fieldAttrMap);
                    }
                }

                return fieldMetaList;
            }
        }


        return Lists.newArrayList();
    }
    /**
     * 获取表单修改的参数列表
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public List<Map<String,Object>> getUpdateApiParam(String moduleCode, ProjectSnapShotBean projectSnapShotBean, String webAppName) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            return Lists.newArrayList();
        }
        ApiBean apiBean = null;
        for (ApiBean api : apiBeanList) {
            if (api.getApiUrl().toLowerCase().contains("update")) {
                apiBean = api;
            }
        }

        if(apiBean != null && CollectionUtils.isNotEmpty(apiBean.getParamBeanList())){
            Optional<ParamBean> paramBeanOptional = apiBean.getParamBeanList().stream().filter(paramBean -> paramBean.isModelParam()).findFirst();
            if(paramBeanOptional.isPresent()){

                ParamBean paramBean = paramBeanOptional.get();
                List<FieldBean> fieldBeanList = paramBean.getFieldBeanList();
                List<Map<String,Object>> fieldMetaList = new ArrayList<>();
                for (FieldBean fieldBean : fieldBeanList){
                    Map<String,Object> fieldAttrMap = new HashMap<>();

                    FieldExtendBean fieldExtendBean = fieldBean.getFieldExtendBean();

                    fieldAttrMap.put("fieldName",fieldBean.getFieldName());
                    fieldAttrMap.put("fieldDesc",fieldBean.getFieldDesc());
                    fieldAttrMap.put("required",fieldExtendBean.isRequired());

                    String inputType = getFieldInputType(fieldBean,webAppName);

                    fieldAttrMap.put("inputType",inputType);
                    fieldAttrMap.put("maxLength",fieldExtendBean.getMaxLength());
                    fieldAttrMap.put("minLength",fieldExtendBean.getMinLength());
                    fieldAttrMap.put("searchInPage",fieldExtendBean.isSearchInPage());
                    //如果不为空或者在插入表单中存在则进行渲染
                    if (fieldExtendBean.isRequired() || fieldExtendBean.isInUpdateForm()){
                        fieldMetaList.add(fieldAttrMap);
                    }
                }

                return fieldMetaList;
            }
        }


        return Lists.newArrayList();
    }

    /**
     * 获取表单修改的参数列表
     *
     * @param moduleCode
     * @param projectSnapShotBean
     * @return
     */
    public List<Map<String,Object>> getPageApiParam(String moduleCode, ProjectSnapShotBean projectSnapShotBean, String webAppName) {
        List<ApiBean> apiBeanList = projectSnapShotBean.getApiBeanListMap().get(moduleCode);

        if (CollectionUtils.isEmpty(apiBeanList)) {
            return Lists.newArrayList();
        }
        ApiBean apiBean = null;
        for (ApiBean api : apiBeanList) {
            if (api.getApiUrl().toLowerCase().contains("update")) {
                apiBean = api;
            }
        }

        if(apiBean != null && CollectionUtils.isNotEmpty(apiBean.getParamBeanList())){
            Optional<ParamBean> paramBeanOptional = apiBean.getParamBeanList().stream().filter(paramBean -> paramBean.isModelParam()).findFirst();
            if(paramBeanOptional.isPresent()){

                ParamBean paramBean = paramBeanOptional.get();
                List<FieldBean> fieldBeanList = paramBean.getFieldBeanList();
                List<Map<String,Object>> fieldMetaList = new ArrayList<>();
                for (FieldBean fieldBean : fieldBeanList){
                    Map<String,Object> fieldAttrMap = new HashMap<>();

                    FieldExtendBean fieldExtendBean = fieldBean.getFieldExtendBean();

                    fieldAttrMap.put("fieldName",fieldBean.getFieldName());
                    fieldAttrMap.put("fieldDesc",fieldBean.getFieldDesc());
                    fieldAttrMap.put("required",fieldExtendBean.isRequired());

                    String inputType = getFieldInputType(fieldBean,webAppName);

                    fieldAttrMap.put("inputType",inputType);
                    fieldAttrMap.put("maxLength",fieldExtendBean.getMaxLength());
                    fieldAttrMap.put("minLength",fieldExtendBean.getMinLength());
                    fieldAttrMap.put("searchInPage",fieldExtendBean.isSearchInPage());
                    //如果不为空或者在插入表单中存在则进行渲染
                    if (fieldExtendBean.isRequired() || fieldExtendBean.isInPageForm()){
                        fieldMetaList.add(fieldAttrMap);
                    }
                }
                return fieldMetaList;
            }
        }


        return Lists.newArrayList();
    }

    /**
     * 根据框架动态确定表单项的类型
     * @param fieldBean
     * @param webAppName
     * @return
     */
    private String getFieldInputType(FieldBean fieldBean, String webAppName){
        CodeFactoryService codeFactoryService = codeFactoryRoute.getByWebArchName(webAppName);
        return codeFactoryService.preBuildComponent(fieldBean);
    }

}
